<?php

namespace App\Http\Controllers;

use DB;
use Illuminate\Http\Request;
use Validator;

use Illuminate\Hashing\BcryptHasher as Hash;

use Cache;
use Carbon\Carbon;

use Ptime3\Functions\Queue;
use Unirest\Request AS API;

class UserController extends Controller
{

    public function index(Request $request){
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'ids'     => 'string|min:1',
                'name'    => 'string|min:1',
                'user_id' => 'integer|min:1',
            ]
        );
        if($validator->fails())
            return $this::jsonResponse(true,$validator->messages(),"paramError");

        $userResult = [];
        if(!empty($input["ids"])){
            $ids = $input["ids"];
            $userResult = DB::table("ur_user")
                ->select("id","name","sex","icon","school_id","description","email","phone","is_actived","is_verified","created_at","token")
                ->whereIn("id",explode(',', $ids))->get();
        }
        if(!empty($input["name"]) && !empty($input["user_id"])){
            $userResult = DB::table("ur_user")
                ->select("id","name","description","icon")
                ->where("name","like","%".$input["name"]."%")
                ->where("is_verified",true)
                ->where("id","!=",$input["user_id"])
                ->take(20)
                ->get();
        }
        return $this->jsonResponse(false,$userResult);
    }

    public function show($userId){
        $userResult = DB::table("ur_user")
            ->select("id","name","sex","icon","school_id","description","email","phone","is_actived","is_verified","created_at","token")
            ->where("id",$userId)->first();
        return $this->jsonResponse(false,$userResult);
    }

    public function store(Request $request){
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'phone'     => 'required|digits:11',
                'password'  => 'min:6',
                'name'      => 'min:1',
                'icon'      => 'min:1',
                'school_id' => 'min:6|unique:ur_user',
                'openid'    => 'min:28|unique:ur_user',
                'email'     => 'email|unique:ur_user',
                'sex'       => 'boolean',
                'token'     => 'min:32'
            ]
        );
        if($validator->fails()){
            return $this::jsonResponse(true,$validator->messages(),"paramError");
        }

        $phone    = $input["phone"];
        $userData = [];

        //验证验证码
        if(!empty($input["token"])){
            if(empty($input["password"]))
                return $this::jsonResponse(true,[],"密码不能为空！");
            if($input["token"] != Cache::get($phone."token",""))
                return $this::jsonResponse(true,[],"token错误！");
            $userData["is_actived"] = true;
        }else{
            $userData["is_actived"] = false;
        }

        //验证手机号
        $userResult = DB::table("ur_user")->select("id","is_actived")->where("phone",$phone)->first();
        if(!empty($userResult) && $userResult->is_actived == true){
            return $this::jsonResponse(true,[],"手机号已被注册。");
        }

        //数据构造
        foreach (["phone","name","icon","school_id","email","sex"] as $value) {
             if(!empty($input[$value]))  $userData[$value] = $input[$value];
        }

        $salt                 = str_random(6);
        $userData["salt"]     = $salt;
        $userData["password"] = !empty($input["password"])?(new Hash)->make($input["password"].$salt):"";
        $userData["icon"]     = !empty($userData["icon"])?$userData["icon"]:"/uploads/default/user".rand(1,5).".png";
        $userData["name"]     = !empty($input["name"])?$input["name"]:"萌新";
        
        //激活已有用户
        if(!empty($userResult)){
            $userId = $userResult->id;
            DB::table("ur_user")->where("id",$userId)->update($userData);
        
        //添加用户
        }else{
            $userId = DB::table("ur_user")->insertGetId($userData);
        }

        //添加用户通知方式
        if(!empty($userData["phone"])){
            $mqData = ["value"=>$userData["phone"],"grade"=>2];
            Queue::put("restapi",["post","inform","user/$userId/method/3",$mqData]);
            $mqData = ["value"=>$userData["phone"]];
            Queue::put("restapi",["post","inform","user/$userId/method/4",$mqData]);
        }
        if(!empty($userData["email"])){
            $mqData = ["value"=>$userData["email"]];
            Queue::put("restapi",["post","inform","user/$userId/method/2",$mqData]);
        }
        if(!empty($userData["openid"])){
            $mqData = ["value"=>$userData["openid"]];
            Queue::put("restapi",["post","inform","user/$userId/method/5",$mqData]);
        }

        //首次注册
        if(empty($userResult))
            Queue::put("restapi",["post","app","user/$userId/app/default",[]]);

        return $this->show($userId);
    }

    public function update(Request $request, $userId){
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'phone'         => 'digits:11',
                'icon'          => 'min:1',
                'email'         => 'email|unique:ur_user',
                'unionid'       => 'min:28',
                'sex'           => 'boolean',
                'openid'        => 'min:28',
                'token'         => 'min:32',
                'password_old'  => 'min:6',
                'password_new'  => 'min:6',

                'name'          => 'string|min:1',
                'description'   => 'string|min:1',
                'school_id'     => 'string|min:1|unique:ur_user',
                'is_verified'   => 'boolean'
            ]
        );
        if($validator->fails())
            return $this::jsonResponse(true,$validator->messages(),"paramError");

        if(!empty($input["unionid"])){
            $unionidUserId = DB::table("ur_user")->where("unionid",$input["unionid"])->pluck("id");
            if(!empty($unionidUserId) && $unionidUserId != $userId)
                return $this::jsonResponse(true,[],"微信号已被绑定。");
        }

        //数据构造
        $userData = [];
        foreach (["icon","email","sex","name","description","school_id","is_verified"] as $value) {
             if(!empty($input[$value]))
                $userData[$value] = $input[$value];
        }
        if(isset($input["unionid"]))
            $userData["unionid"] = $input["unionid"];

        //更新手机号
        if(!empty($input["phone"]) && !empty($input["token"])){
            $phone = $input["phone"];
            $userResult = DB::table("ur_user")->where("phone",$phone)->first();
            if(!empty($userResult))
                return $this::jsonResponse(true,[],"手机号已被注册。");

            $token = Cache::get($phone."token","");
            if( $token=="" || $input["token"] != $token)
                return $this::jsonResponse(true,[],"token错误！");
        
            $userData["phone"] = $phone;
        }

        //更新密码
        if(!empty($input["password_old"]) && !empty($input["password_new"]) ){
            $userResult = DB::table("ur_user")
                ->select("password","salt")
                ->where("id",$userId)->first();
            
            if(empty($userResult))
                return $this::jsonResponse(true,[],"用户不存在。");

            $password_old = $input["password_old"];
            $password_new = $input["password_new"];

            $ckeckResult  = (new Hash)->check($password_old.$userResult->salt,$userResult->password);
            if(!$ckeckResult){
                return $this::jsonResponse(true,[],"原密码错误。");
            }

            $password_new         = (new Hash)->make($password_new.$userResult->salt);
            $token                = md5($userId.time().str_random(6));  
            $userData["password"] = $password_new;
            $userData["token"]    = $token;
        }

        if(empty($userData))
            return $this->jsonResponse(true,$input,"用户更新失败。");

        //更新用户数据
        $userUpdateResult = DB::table("ur_user")
            ->where("id",$userId)->update($userData);

        //更新用户通知方式
        if(!empty($userData["email"])){
            $mqData = ["value"=>$userData["email"]];
            Queue::put("restapi",["post","inform","user/$userId/method/2",$mqData]);
        }
        if(!empty($userData["phone"])){
            $mqData = ["value"=>$userData["phone"]];
            Queue::put("restapi",["post","inform","user/$userId/method/3",$mqData]);
            Queue::put("restapi",["post","inform","user/$userId/method/4",$mqData]);
        }
        if(!empty($input["openid"])){
            $mqData = ["value"=>$input["openid"]];
            Queue::put("restapi",["post","inform","user/$userId/method/5",$mqData]);
        }

        return $this->show($userId);
    }

    public function destroy($userId){
        $userUpdateResult = DB::table("ur_user")->where("id",$userId)->update(
            [
                "password"   =>"",
                "school_id"  =>"",
                "unionid"    =>"",
                "email"      =>"",
                "is_actived" =>false,
                "is_verified"=>false
            ]);
        $phone = DB::table("ur_user")->where("id",$userId)->value("phone");
        Cache::forget($phone."limit");
        return $this::jsonResponse(false,$userUpdateResult);
    }

    public function showWithToken($token){
        $userId = DB::table("ur_user")->where("token",$token)->value("id");
        if(empty($userId))
            $this->jsonResponse(true,[],"token错误！");

        return $this->show($userId);
    }

    public function showWithUnionid($unionid){
        $userId = DB::table("ur_user")->where("unionid",$unionid)->value("id");
        if(empty($userId))
            $this->jsonResponse(true,[],"Unionid错误！");

        return $this->show($userId);
    }

    public function showWithPhone($phone){
        $input = ["phone"=>$phone];
        //参数检验
        $validator = Validator::make($input,
            [
                'phone'     => 'required|digits:11'
            ]
        );
        if($validator->fails())
            return $this::jsonResponse(true,$validator->messages(),"paramError");

        $userId = DB::table("ur_user")->where("phone",$phone)->value("id");
        if(empty($userId))
            $this->jsonResponse(true,[],"phone错误！");

        return $this->show($userId);
    }

    public function exist(Request $request){
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'phone'     => 'required|digits:11'
            ]
        );
        if($validator->fails())
            return $this::jsonResponse(true,$validator->messages(),"paramError");

        $userId = DB::table("ur_user")->where("phone",$input["phone"])->value("id");
        if(!empty($userId))
            return $this->jsonResponse(true,$userId,"用户已存在");

        return $this->jsonResponse(false,true);
    }

    public function login(Request $request)
    {
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'username' => 'required|min:1',
                'password' => 'required|min:6',
                'from_web' => 'boolean',
            ]
        );
        if($validator->fails())
            return $this::jsonResponse(true,$validator->messages(),"paramError");

        $username = strtoupper($input["username"]); 
        $password = $input["password"]; 

        //手机登录
        $userResult = DB::table("ur_user")
            ->select("id","is_actived","password","salt","token")
            ->where("phone",$username)->first();

        //学号登录
        if(empty($userResult)){
            $userResult = DB::table("ur_user")
                ->select("id","is_actived","password","salt","token")
                ->where("school_id",$username)->first();
        }
        if(empty($userResult) || $userResult->is_actived == false)
            return $this::jsonResponse(true,[],"用户不存在。");

        $ckeckResult = (new Hash)->check($password.$userResult->salt,$userResult->password);
        if(!$ckeckResult)
            return $this::jsonResponse(true,[],"密码错误。");

        $userId = $userResult->id;

        if(empty($userResult->token) || empty($input["from_web"])){
            $token = md5($userId.time().str_random(6));
            DB::table("ur_user")->where("id",$userId)->update(["token"=>$token]);
        }

        return $this->show($userId);
    }

    public function logout(Request $request, $userId)
    {
        if($request->ajax())
            return $this::jsonResponse(false,true);

        $userResult = DB::table("ur_user")->where("id",$userId)->update(["token"=>""]);

        //取消推送关联
        Queue::put("restapi",["delete","inform","user/$userId/method/1",[]]);

        return $this::jsonResponse(false,$userResult);
    }

    public function verifycode(Request $request)
    {
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'phone'      => 'required|digits:11',
                'need_unique'=> 'boolean',
                'need_exist' => 'boolean'
            ]
        );
        if($validator->fails()){
            return $this::jsonResponse(true,$validator->messages(),"paramError");
        }

        $phone = $input["phone"];

        if(!empty($input["need_unique"])){
            $userResult = DB::table("ur_user")->where("phone",$phone)->where("is_actived","=",true)->first();
            if(!empty($userResult))
                return $this::jsonResponse(true,[],"手机号已被注册。");
        }

        if(!empty($input["need_exist"])){
            $userResult = DB::table("ur_user")->where("phone",$phone)->where("is_actived","=",true)->first();
            if(empty($userResult))
                return $this::jsonResponse(true,[],"手机号还未注册或激活。");
        }

        $verifyCode = rand(1000,9999);
        
        if(!Cache::add($phone."limit", "", 1))
            return $this::jsonResponse(true,[],"请稍后发送！");

        Cache::put($phone, $verifyCode, Carbon::now()->addMinutes(15));

        if($phone == "15232326682")
            return $this::jsonResponse(false,["verifycode"=>$verifyCode]);

        $mqData = [
            "id"     => 0,
            "text"   => "【拾光通知】您的验证码是".$verifyCode,
            "mobile" => $phone
        ];
        //Queue::put("inform",["sms",$mqData]);


        $encodedText  =  urlencode("【拾光通知】您的验证码是".$verifyCode);
        $postString   = "apikey=5b5f3ef06ab12542896076c854e8417c&text=$encodedText&mobile=".$phone;
        $ch = curl_init();
        curl_setopt ( $ch, CURLOPT_URL, "http://yunpian.com/v1/sms/send.json" );
        curl_setopt ( $ch, CURLOPT_POST, 1 );
        curl_setopt ( $ch, CURLOPT_HEADER, 0 );
        curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt ( $ch, CURLOPT_HTTPHEADER, array("Expect:") );
        curl_setopt ( $ch, CURLOPT_POSTFIELDS, $postString );
        curl_exec ( $ch );
        curl_close ( $ch );


        return $this::jsonResponse(false,true);
    }

    public function verifycodeVerify(Request $request)
    {
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'phone'      => 'required|digits:11',
                'verifycode' => 'required|digits:4'
            ]
        );
        if($validator->fails()){
            return $this::jsonResponse(true,$validator->messages(),"paramError");
        }

        $phone      = $input["phone"];
        $verifyCode = Cache::get($phone,"");

        if($verifyCode == "")
            return $this::jsonResponse(true,[],"验证码已过期！");

        if($input["verifycode"] != $verifyCode)
            return $this::jsonResponse(true,[],"验证码错误！");

        $token = md5($phone.time().str_random(6));
        Cache::put($phone."token", $token, Carbon::now()->addMinutes(15));
        return $this::jsonResponse(false,["token"=>$token]);
    }


    public function verifyemail(Request $request)
    {
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'user_id'    => 'required|min:1',
                'email'      => 'required|email'
            ]
        );
        if($validator->fails()){
            return $this::jsonResponse(true,$validator->messages(),"paramError");
        }

        $userId = $input["user_id"];
        $email  = $input["email"];

        $userResult = DB::table("ur_user")->where("email",$email)->where("is_actived","=",true)->first();
        if(!empty($userResult))
            return $this::jsonResponse(true,[],"邮箱已被绑定。");

        $verifyCode = str_random(6);
        
        if(!Cache::add($email."limit", "", 1))
            return $this::jsonResponse(true,[],"请稍后发送！");

        Cache::put($verifyCode, $email.":".$userId, Carbon::now()->addMinutes(15));

        $mqData = [
            "id"       => 0,
            "from"     => "service@timepicker.cn",
            "to"       => [$email],
            "tpl_name" => "email_bind",
            "subject"  => "邮箱绑定验证",
            "sub"      => ["%url%"=>["http://".env("APP_URL")."/ev/".$verifyCode]]
        ];
        //Queue::put("inform",["email",$mqData]);

        return $this::jsonResponse(false,true);
    }


    public function findpassword(Request $request)
    {
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'phone'      => 'required|digits:11',
                'password'   => 'required|min:6',
                'token'      => 'min:32',
                'verifycode' => 'digits:4'
            ]
        );
        if($validator->fails()){
            return $this::jsonResponse(true,$validator->messages(),"paramError");
        }

        $phone = $input["phone"];
        
        if(isset($input["verifycode"])){
            $verifyCode = Cache::get($phone,"");
            if($verifyCode == "")
                return $this::jsonResponse(true,[],"验证码已过期！");

            if($input["verifycode"] != $verifyCode)
                return $this::jsonResponse(true,[],"验证码错误！");

        }else if(isset($input["token"])){
            $token = Cache::get($phone."token","");
            if($token == "" || $input["token"] != $token)
                return $this::jsonResponse(true,[],"token错误！");

        }else{
            return $this::jsonResponse(true,[],"修改失败！");
        }

        $userResult = DB::table("ur_user")
            ->select("id","password","salt")
            ->where("phone",$phone)->first();
        
        if(empty($userResult))
            return $this::jsonResponse(true,[],"用户不存在。");
        
        $userId   = $userResult->id;
        $password = (new Hash)->make($input["password"].$userResult->salt);
        $token    = md5($userId.time().str_random(6));  
        
        $userData = [
            "password" => $password,
            "token"    => $token
        ];

        $userUpdateResult = DB::table("ur_user")
            ->where("id",$userId)->update($userData);

        return $this->show($userId);
    }

    function upgradeinform(){
        // $postString = "apikey=5b5f3ef06ab12542896076c854e8417c&start_time=2016-09-03 11:46:00&end_time=2016-09-03 12:46:00&page_num=1&page_size=700";
        // $ch = curl_init();
        // curl_setopt ( $ch, CURLOPT_URL, "https://sms.yunpian.com/v1/sms/get_record.json" );
        // curl_setopt ( $ch, CURLOPT_POST, 1 );
        // curl_setopt ( $ch, CURLOPT_HEADER, 0 );
        // curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
        // curl_setopt ( $ch, CURLOPT_HTTPHEADER, array("Expect:") );
        // curl_setopt ( $ch, CURLOPT_POSTFIELDS, $postString );
        // $response = curl_exec ( $ch );
        // curl_close ( $ch );
        // $response = json_decode($response);
        // $txt = "";
        // foreach ($response->sms as $key => $value) {
        //     $txt .= $value->mobile."\r\n";
        // }
        // echo $txt;

        // $sended = file_get_contents("send.txt");
        // $sended = explode("\r\n", $sended);


        // $phones = file_get_contents("php.txt");
        // $phones = explode("\r\n", $phones);
        // foreach ($phones as $key => $phone) {
        //     if(!in_array($phone, $sended)){
        //         echo $phone;
        //         echo "\r\n";
        //     }
        //     //Queue::put("restapi",["get","inform","/",["phone"=>$phone]]);
        // }

        //
//         $phones = file_get_contents("wait.txt");
//         $phones = explode("\r\n", $phones);
// foreach ($phones as $key => $phone) {
//         $apikey       = "5b5f3ef06ab12542896076c854e8417c";
//         $url          = "http://yunpian.com/v1/sms/send.json";
       
//             $encodedText  =  urlencode("【拾光通知】我是拾光，我的2.0版本（安卓/微信）正在上线，期间无法使用还请谅解。回复我：http://timepicker.cn");
//             $postString   = "apikey=$apikey&text=$encodedText&mobile=".$phone;
            
//             $temp_uri = $url;
//             $temp_data = $postString;
//             $ch = curl_init();
//             curl_setopt ( $ch, CURLOPT_URL, $temp_uri );
//             curl_setopt ( $ch, CURLOPT_POST, 1 );
//             curl_setopt ( $ch, CURLOPT_HEADER, 0 );
//             curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
//             curl_setopt ( $ch, CURLOPT_HTTPHEADER, array("Expect:") );
//             curl_setopt ( $ch, CURLOPT_POSTFIELDS, $temp_data );
//             $temp_post_result = curl_exec ( $ch );
//             curl_close ( $ch );

//             $sendTime = date("Y-m-d H:i:s");
//             $result = ["send_code"=>"1","send_time"=>$sendTime,"send_detail"=>$temp_post_result];
        
//         echo json_encode($result);
// }

        echo "ok";
    }
    


}
